#include <sdk.h>
#include <configurationpanel.h>
#include <manager.h>
#include <logmanager.h>
#include <projectmanager.h>
#include <configmanager.h>
#include <editormanager.h>
#include <M_Code_project.h>
#include <wx/menu.h>
#include <wx/filedlg.h>
#include "HexEditor.h"
#include "HexEditPanel.h"

namespace {
  PluginRegistrant<HexEditor> reg( _T( "HexEditor" ) );

  const int idOpenHexEdit = wxNewId();
  const int idOpenWithHE = XRCID( "idOpenWithHE" );
  const int idOpenHexEditFileBrowser = wxNewId();
}

BEGIN_EVENT_TABLE( HexEditor, M_Code_Plugin )
  EVT_MENU( idOpenHexEdit, HexEditor::OnOpenHexEdit )
  EVT_MENU( idOpenHexEditFileBrowser, HexEditor::OnOpenHexEditFileBrowser )
  EVT_MENU( idOpenWithHE, HexEditor::OnOpenWithHE )
END_EVENT_TABLE()

HexEditor::HexEditor() {
}

HexEditor::~HexEditor() {
}

void HexEditor::OnAttach() {
}

void HexEditor::OnRelease( bool appShutDown ) {
  if( !appShutDown ) {
    CloseMyEditors();
  }
}

bool HexEditor::BuildToolBar( wxToolBar* ) {
  return false;
}

void HexEditor::BuildModuleMenu( const ModuleType type, wxMenu* menu, const FileTreeData* data ) {
  if( !menu || !IsAttached() ) {
    return;
  }
  switch( type ) {
    case mtProjectManager:
      if( data && data->GetKind() == FileTreeData::ftdkFile ) {
        wxMenuItem* child = menu->FindItem( menu->FindItem( _T( "打开" ) ) );
        if( child && child->IsSubMenu() ) {
          menu = child->GetSubMenu();
        }
        menu->Append( idOpenHexEdit, _T( "HexEditor" ) );
      }
      break;
    case mtUnknown:
      if( data && data->GetKind() == FileTreeData::ftdkFile ) {
        wxFileName f( data->GetFolder() );
        m_browserselectedfile = f.GetFullPath();
        wxMenuItem* child = menu->FindItem( menu->FindItem( _T( "打开" ) ) );
        if( child && child->IsSubMenu() ) {
          menu = child->GetSubMenu();
        }
        menu->Append( idOpenHexEditFileBrowser, _T( "HexEditor" ) );
      }
      break;
    case mtEditorManager:
    case mtLogManager:
    case mtOpenFilesList:
    case mtEditorTab:
    default:
      break;
  }
}

void HexEditor::OnOpenHexEditFileBrowser( wxCommandEvent& ) {
  OpenFileFromName( m_browserselectedfile );
}

void HexEditor::OnOpenHexEdit( wxCommandEvent& ) {
  cbProjectManagerUI &managerUI = Manager::Get()->GetProjectManager()->GetUI();
  wxTreeCtrl *tree = managerUI.GetTree();
  if( !tree ) {
    return;
  }
  wxTreeItemId treeItem =  managerUI.GetTreeSelection();
  if( !treeItem.IsOk() ) {
    return;
  }
  const FileTreeData *data = static_cast<FileTreeData*>( tree->GetItemData( treeItem ) );
  if( !data ) {
    return;
  }
  if( data->GetKind() == FileTreeData::ftdkFile ) {
    OpenProjectFile( data->GetProjectFile() );
  }
}

void HexEditor::OpenProjectFile( ProjectFile* f ) {
  if( !f ) {
    return;
  }
  if( Manager::Get()->GetEditorManager()->IsOpen( f->file.GetFullPath() ) ) {
    InfoWindow::Tip(_T("此文件已在编辑器中打开"),_T("提示"),2500);
    return;
  }
  wxString title;
  if( Manager::Get()->GetConfigManager( _T( "editor" ) )->ReadBool( _T( "/tab_text_relative" ), true ) ) {
    title = f->relativeToCommonTopLevelPath;
  } else {
    title = f->file.GetFullName();
  }
  new HexEditPanel( f->file.GetFullPath(), title );
}

void HexEditor::OpenFileFromName( const wxString& fileName ) {
 if( Manager::Get()->GetEditorManager()->IsOpen( fileName ) ) {
    InfoWindow::Tip(_T("此文件已在编辑器中打开"),_T("提示"),2500);
    return;
  }
  wxString title = wxFileName( fileName ).GetFullName();
  HexEditPanel( fileName, title );
}

void HexEditor::OnOpenWithHE( wxCommandEvent& ) {
  wxString file = ::wxFileSelector( _( "HexEditor" ) );
  if( file.IsEmpty() ) {
    return;
  }
  ProjectFile* f = FindProjectFile( file );
  if( f ) {
    OpenProjectFile( f );
  } else {
    OpenFileFromName( file );
  }
}

ProjectFile* HexEditor::FindProjectFile( const wxString& fileName ) {
  ProjectsArray* projects = ProjectManager::Get()->GetProjects();
  if( !projects ) {
    return 0;
  }
  for( size_t i = 0; i < projects->Count(); ++i ) {
    M_Code_Project* project = ( *projects )[i];
    if( !project ) {
      continue;
    }
    ProjectFile* file = project->GetFileByFilename( fileName, false, false );
    if( file ) {
      return file;
    }
  }
  return 0;
}

void HexEditor::CloseMyEditors() {
  HexEditPanel::CloseAllEditors();
}
